ruby 請問這個東西被定義過了嗎? 使用關鍵字可以檢查變數是否已經被定義過。如果變數已經存在就出現:
apple = 1
defined?(apple)
# "local-variable"
如果不存在你會得到 nil
defined?(bacon)
# nil
這就像是 Javascript’s typeof。如果想要知道一個物件的類別可以用 class 這個方法。
defined? 是少數在 ruby 裡面用問號結尾的,但不會像一般的慣例去回傳一個 true 或是 false。
defined? 可以告訴你變數是否被定義過,是 nil 還是其他類型的變數。這個特別的屬性很直得記起來用。
這個關鍵字很好用,但是會有一些問題。因為較低的優先權。
defined? orange && orange.size
結果會是 “expression”.
因為 orange && orange.size 引數是否被定義過。
但是正確的方法應該是這樣做:
defined?(orange) && orange.size
Ruby 還有其他的方法可以檢查變數是否被定義過。
對於區域變數:
local_variables.include?(:orange)
對於實體變數:
instance_variable_defined?("@food")
這種寫法讓人失去想要使用的動力。
在 99% 的例子,如果一個區域變數不見了,可能是打錯字或是根本忘記了定義。那實體變數呢?還沒定義過的實體變數永遠都是 nil ,所以會想要去檢查看看是否有定義過。
可以用 defined? 關鍵字去檢查方法有沒有被定義過,但是實務上不太這麼做。
defined?(puts)
# "method"
因為是一個關鍵字不是一個方法,沒辦法在一個物件上直接呼叫。意思就是說:
[].defined?(:size)
# undefined method `defined?' for []:Array
你需要的是 respond_to? 方法。
[].respond_to?(:size)
# true
[].respond_to?(:orange)
# false
defined?(Object)
# "constant"
defined?(A)
# nil
有個更好的選擇可以使用 const_defined? 方法。像是這樣:
Object.const_defined?(:String)
# true
Object.const_defined?(:A)
# false
當你在使用變數的時候,會想要知道變數是否為 nil,或變數是否已經被定義。或是用更好的方法,將變數轉換到類別裡用慣例的方法。